home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Interactive Web Graphics with Shout 3D
/
Interactive Web Graphics With Shout 3D.iso
/
pc
/
Shout3Ddemo
/
Shout3d_runtime
/
codebase
/
custom_nodes
/
TintedImageTexture.java
< prev
next >
Wrap
Text File
|
2000-09-01
|
5KB
|
124 lines
/**
Company: Eyematic Interfaces
Project: Shout3D 2.0 Sample Code
Class: TintedImageTexture
Date: July 12, 2000
Description: A subclass of ImageTexture that tints the pixels of the texture.
(C) Copyright Eyematic Interfaces, Inc. - 1997-2000 - All rights reserved
*/
package custom_nodes;
import shout3d.core.*;
import shout3d.*;
import java.awt.Graphics;
/**
* TintedImageTexture
*
* A subclass of ImageTexture that tints the pixels of the texture.
*
* Demonstrates how to use the API on PixelBasedTexture (from which
* ImageTexture is derived) to take the pixels from the url and then
* image process them to create a new texture.
*
* @author Paul Isaacs
*/
public class TintedImageTexture extends ImageTexture {
final public FloatArrayField tintColor = new FloatArrayField(this, "tintColor", Field.COLOR, null);
/**
* Constructs a default TintedImageTexture node.
*/
public TintedImageTexture(){
// Setting this true specifies that any change in the url field causes the
// texture file to be fetched immediately, and in the same thread. When
// reading from file, the texture is fetched immediately upon reading the
// url field.
// This insures that once this classes' onFieldChange calls the super class
// method of the same name,
// there is no chance there there is a texture loading in another thread or
// waiting to be loaded.
// Hence, updateCustomPixels() will always take effect properly.
loadASAP.setValue(true);
tintColor.addFieldObserver(this,null);
}
public void finalize() throws Throwable {
tintColor.removeFieldObserver(this);
super.finalize();
}
public void onFieldChange(Field theField, Object userData) {
// First, call the base class.
super.onFieldChange(theField, userData);
// When these fields change, new pixels are loaded into the node
// based on the fetched url. Save them for reference purposes in
// generateCustomPixels().
if (theField == url || theField == hasAlphaTexture || theField == loadASAP ){
// false means don't copy, just get a reference.
// These arrays will not be edited by this node.
urlsRed = getChannel(RED, false);
urlsGreen = getChannel(RED, false);
urlsBlue = getChannel(RED, false);
}
// When these fields change, a new texture must be generated by
// tinting the texture that was read from the url.
if (theField == url || theField == hasAlphaTexture || theField == loadASAP ||
theField == tintColor){
generateCustomPixels();
}
}
byte[][] urlsRed, urlsGreen, urlsBlue;
byte[][] myRed, myGreen, myBlue;
public void generateCustomPixels(){
if (tintColor.getValue() == null || tintColor.getValue().length != 3 ||
urlsRed == null || urlsGreen == null || urlsBlue == null ||
urlsRed.length == 0 ||
urlsGreen.length != urlsRed.length || urlsBlue.length != urlsRed.length){
// Do not tint. Use the original pixels.
// The alpha can just be set to a reference to the current alpha.
setCustomPixels(getWidth(), getHeight(), urlsRed, urlsGreen, urlsBlue,
getChannel(ALPHA, false));
}
else {
// Time to tint.
// Get copies of the texture into myRed, myGreen, myBlue if needed.
if (myRed == null ||
myRed.length != urlsRed.length ||
myRed[0].length != urlsRed[0].length){
myRed = getChannel(RED, true);
myGreen = getChannel(GREEN, true);
myBlue = getChannel(BLUE, true);
}
// Tint the pixels based on the original:
if (urlsRed != null){
for (int i = 0; i < urlsRed.length; i++){
for (int j = 0; j < urlsRed[0].length; j++){
// To read from a byte value (which ranges [-128..128]) into a
// value [0..255], you need to do an & with 0x255, as in:
// (urlRed[i][j] & 0x255)
// Following this, the number can be multiplied by the tintColor,
// expressed with values in the range [0..1] and cast back to a byte
// into myRed.
myRed[i][j] = (byte) (tintColor.getValue()[0] * (urlsRed[i][j] & 0xff));
myGreen[i][j] = (byte) (tintColor.getValue()[1] * (urlsGreen[i][j] & 0xff));
myBlue[i][j] = (byte) (tintColor.getValue()[2] * (urlsBlue[i][j] & 0xff));
}
}
// For alpha, use a reference to the existing channel. The
// false argument means reference, not copy.
setCustomPixels(getWidth(), getHeight(),
myRed, myGreen, myBlue,
getChannel(ALPHA, false));
}
}
}
}